﻿using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using System.Linq;

namespace Microsoft.OpportunityPortal.GenericEventRcvr
{
    /// <summary>
    /// List Item Events
    /// </summary>
    public class GenericEventRcvr : SPItemEventReceiver
    {
        /// <summary>
        /// An item was updated.
        /// </summary>
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            base.ItemUpdated(properties);

            ProcessListEvents(properties);
        }

        /// <summary>
        /// An item is being deleted.
        /// </summary>
        /// <param name="properties"></param>

        public override void ItemDeleting(SPItemEventProperties properties)
        {
            base.ItemDeleting(properties);

            ProcessListEvents(properties);
        }

        public override void ItemDeleted(SPItemEventProperties properties)
        {
            base.ItemDeleted(properties);

            ProcessListEvents(properties);
        }

        public override void ItemUpdating(SPItemEventProperties properties)
        {
            base.ItemUpdating(properties);

            ProcessListEvents(properties);
        }

        /// <summary>
        /// An item was added.
        /// </summary>
        public override void ItemAdded(SPItemEventProperties properties)
        {
            base.ItemAdding(properties);

            string title = properties.ListItem["Title"].ToString();
            bool siteExists = false;

            // Check if the Site URL exists or not. If yes, throw an exception
            try
            {
                if (properties.Web.Webs[title] != null && false == string.IsNullOrEmpty(properties.Web.Webs[title].Url))
                {
                    siteExists = true;
                    throw new Exception("Site exists with the given title. Please use some other title.");
                }
            }
            catch (Exception)
            {
                if (siteExists)
                {
                    properties.Cancel = true;
                    throw new Exception("Site exists with the given title. Please use some other title.");
                }
            }
        }

        private void ProcessListEvents(SPItemEventProperties properties)
        {
            lock (this)
            {
                // Check the list for which event was fired
                string listTitle = properties.ListTitle;
                bool result = false;

                switch (listTitle)
                {
                    case "Opportunity Requests":
                        {
                            if (properties.EventType == SPEventReceiverType.ItemUpdating)
                            {
                                // Execute the below logic only when the Opportunity Status is either Reviewed, Submitted, Closed or Cancelled
                                if (properties.AfterProperties["OpportunityStatus"] != null &&
                                    (string.Compare(properties.AfterProperties["OpportunityStatus"].ToString(), "Reviewed") == 0 ||
                                    string.Compare(properties.AfterProperties["OpportunityStatus"].ToString(), "Approved") == 0 ||
                                    string.Compare(properties.AfterProperties["OpportunityStatus"].ToString(), "Closed") == 0 ||
                                    string.Compare(properties.AfterProperties["OpportunityStatus"].ToString(), "Cancelled") == 0))
                                {
                                    // Check if the logged in user is part of approver group or not
                                    System.Collections.Generic.List<string> groupNames = new System.Collections.Generic.List<string>();
                                    groupNames.Add("Reviewers");
                                    groupNames.Add("Approvers");

                                    // Allow update operation only when the user is part of Reviwers or Approvers group or user is a item creator.
                                    if (!(true == SPOperations.IsUserItemCreator(properties.ListItem["Modified By"].ToString(), properties) ||
                                        true == SPOperations.IsMember(properties.WebUrl, groupNames)))
                                    {
                                        // if user is not part of reviewer or approver group then cancel the event.
                                        properties.Cancel = true;
                                        properties.ErrorMessage = "Unauthorized operation performed by the user.";
                                        return;
                                    }
                                }
                            }

                            if (properties.EventType == SPEventReceiverType.ItemUpdated)
                            {
                                // Disable event firing
                                EventFiringEnabled = false;
                                result = OpportunityRequest.ProcessOpportunityRequestEvent(properties);
                                EventFiringEnabled = true;
                            }

                            break;
                        }                   
                    default:
                        break;
                }
            }
        }


    }
}
